<script setup lang="ts">
import { onMounted, ref, reactive, h } from "vue";
import { DynamicTable } from "@/components/DynamicTable";
import { PaginationConfig, TableColumn } from "@/components/DynamicTable/types";
import DynamicForm from "@/components/DynamicForm/index.vue";
import type { DynamicFormInstance } from "@/components/DynamicForm/types";
import { FormItemConfig } from "@/components/DynamicForm/types";
import {
  ElMessage,
  ElMessageBox,
  ElDialog,
  ElDescriptions,
  ElTag,
  ElUpload,
  ElCard,
  ElSwitch,
} from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import {
  getMemshellList,
  getMemshellDetail,
  updateMemshell,
  toggleMemshell,
  deleteMemshell,
  generateMemshell,
  uploadMemshell,
  addMemshell,
} from "../servers";

const pagination = reactive<PaginationConfig>({
  currentPage: 1,
  pageSize: 20,
  total: 0,
  pageSizes: [10, 20, 50, 100],
  layout: "total, sizes, prev, pager, next",
  background: true,
});

const memshellList = ref([]);
const loading = ref(false);
const searchFormRef = ref<DynamicFormInstance>();

// 搜索表单
const searchForm = reactive({
  shell_type: "",
  target_middleware: "",
  risk_level: "",
  is_available: "",
  is_template: "",
  search: "",
});

const searchConfig: FormItemConfig[] = [
  {
    key: "shell_type",
    name: "类型",
    type: "select",
    placeholder: "选择类型",
    labelWidth: "60px",
    options: [
      { label: "全部", value: "" },
      { label: "Servlet", value: "Servlet" },
      { label: "Filter", value: "Filter" },
      { label: "Listener", value: "Listener" },
      { label: "Agent", value: "Agent" },
      { label: "Spring", value: "Spring" },
      { label: "JNDI", value: "JNDI" },
      { label: "Valve", value: "Valve" },
      { label: "WebSocket", value: "WebSocket" },
    ],
    params: {
      clearable: true,
      showPlaceholder: false,
    },
  },
  {
    key: "target_middleware",
    name: "中间件",
    type: "input",
    placeholder: "搜索中间件",
    params: {
      clearable: true,
      style: { width: "200px" },
    },
  },
  {
    key: "risk_level",
    name: "风险等级",
    type: "select",
    placeholder: "选择风险等级",
    options: [
      { label: "全部", value: "" },
      { label: "严重", value: "critical" },
      { label: "高危", value: "high" },
      { label: "中危", value: "medium" },
      { label: "低危", value: "low" },
    ],
    params: {
      clearable: true,
      style: { width: "200px" },
      showPlaceholder: false,
    },
  },
  {
    key: "is_available",
    name: "状态",
    type: "select",
    placeholder: "选择状态",
    options: [
      { label: "全部", value: "" },
      { label: "可用", value: "true" },
      { label: "禁用", value: "false" },
    ],
    params: {
      clearable: true,
      style: { width: "200px" },
      showPlaceholder: false,
    },
  },
  {
    key: "is_template",
    name: "是否模板",
    type: "select",
    placeholder: "选择是否模板",
    options: [
      { label: "全部", value: "" },
      { label: "是", value: "true" },
      { label: "否", value: "false" },
    ],
    params: {
      clearable: true,
      style: { width: "200px" },
      showPlaceholder: false,
    },
  },
  {
    key: "search",
    name: "关键词",
    type: "input",
    placeholder: "搜索名称/描述/标签",
    params: {
      clearable: true,
      style: { width: "200px" },
    },
  },
];

const columns = ref<TableColumn[]>([
  {
    label: "ID",
    prop: "id",
    width: 80,
    show: true,
  },
  {
    label: "名称",
    prop: "shell_name",
    minWidth: 200,
    show: true,
  },
  {
    label: "类型",
    prop: "shell_type",
    width: 120,
    show: true,
  },
  {
    label: "目标中间件",
    prop: "target_middleware",
    width: 150,
    show: true,
  },
  {
    label: "风险等级",
    prop: "risk_level",
    width: 100,
    show: true,
    render: (row) => {
      const riskMap = {
        critical: { text: "严重", type: "danger" },
        high: { text: "高危", type: "danger" },
        medium: { text: "中危", type: "warning" },
        low: { text: "低危", type: "success" },
      };
      const item = riskMap[row.risk_level] || {
        text: row.risk_level,
        type: "",
      };
      return h(ElTag, { type: item.type, size: "small" }, () => item.text);
    },
  },
  {
    label: "功能特性",
    prop: "capabilities",
    minWidth: 200,
    show: true,
    render: (row) => {
      return h(
        "div",
        {},
        [
          row.has_cmd_shell &&
            h(
              ElTag,
              { type: "danger", size: "small", style: "margin-right: 4px" },
              () => "命令"
            ),
          row.has_file_upload &&
            h(
              ElTag,
              { type: "warning", size: "small", style: "margin-right: 4px" },
              () => "上传"
            ),
          row.has_file_download &&
            h(
              ElTag,
              { type: "info", size: "small", style: "margin-right: 4px" },
              () => "下载"
            ),
          row.has_reverse_shell &&
            h(
              ElTag,
              { type: "success", size: "small", style: "margin-right: 4px" },
              () => "反弹"
            ),
        ].filter(Boolean)
      );
    },
  },
  {
    label: "是否模板",
    prop: "is_template",
    width: 100,
    show: true,
    render: (row) => {
      return h(
        ElTag,
        { type: row.is_template ? "warning" : "info", size: "small" },
        () => (row.is_template ? "是" : "否")
      );
    },
  },
  {
    label: "状态",
    prop: "is_available",
    width: 100,
    show: true,
    slot: "status",
  },
  {
    label: "上传时间",
    prop: "uploaded_at",
    width: 160,
    show: true,
  },
  {
    label: "操作",
    prop: "action",
    width: 300,
    show: true,
    slot: "action",
    fixed: "right",
  },
]);

// 上传相关
const uploadDialogVisible = ref(false);
const uploadFileList = ref([]);
const uploadForm = reactive({
  shell_name: "",
  shell_type: "",
  uploaded_by: "admin",
});

// 新增相关
const addDialogVisible = ref(false);
const addForm = reactive({
  shell_name: "",
  shell_type: "",
  description: "",
  java_code: "",
  target_middleware: "",
  target_framework: "",
  jdk_version: "",
  has_cmd_shell: false,
  has_file_upload: false,
  injection_method: "",
  risk_level: "",
  tags: "",
  is_template: false,
  author: "",
  uploaded_by: "admin",
});

// 详情相关
const detailDialogVisible = ref(false);
const detailData = ref(null);

// 编辑相关
const editDialogVisible = ref(false);
const editForm = reactive({
  shell_id: null,
  shell_name: "",
  description: "",
  risk_level: "",
  tags: "",
  is_available: null,
});

// 生成代码相关
const generateDialogVisible = ref(false);
const generateForm = reactive({
  shell_id: null,
  password: "",
  callback_url: "",
  callback_port: "",
});
const generatedCode = ref("");
const generatedData = ref(null);

// 获取列表
const fetchMemshellList = async () => {
  loading.value = true;
  try {
    const params: any = {
      page: pagination.currentPage,
      page_size: pagination.pageSize,
      ...searchForm,
    };
    // 移除空值
    Object.keys(params).forEach((key) => {
      if (
        params[key] === "" ||
        params[key] === null ||
        params[key] === undefined
      ) {
        delete params[key];
      }
    });
    const { data } = await getMemshellList(params);
    memshellList.value = data.items || [];
    pagination.total = data.total || 0;
  } catch (error) {
    ElMessage.error("获取内存马列表失败");
  } finally {
    loading.value = false;
  }
};

const handleSearch = (value: any) => {
  searchForm.shell_type = value.shell_type || "";
  searchForm.target_middleware = value.target_middleware || "";
  searchForm.risk_level = value.risk_level || "";
  searchForm.is_available = value.is_available || "";
  searchForm.is_template = value.is_template || "";
  searchForm.search = value.search || "";
  pagination.currentPage = 1;
  fetchMemshellList();
};

const handleSearchReset = () => {
  searchFormRef.value?.resetFields();
  searchForm.shell_type = "";
  searchForm.target_middleware = "";
  searchForm.risk_level = "";
  searchForm.is_available = "";
  searchForm.is_template = "";
  searchForm.search = "";
  pagination.currentPage = 1;
  fetchMemshellList();
};

const handlePageChange = (page: number) => {
  pagination.currentPage = page;
  fetchMemshellList();
};

const handleSizeChange = (size: number) => {
  pagination.pageSize = size;
  pagination.currentPage = 1;
  fetchMemshellList();
};

// 上传
const handleUpload = () => {
  uploadDialogVisible.value = true;
};

const beforeUpload = (file: any) => {
  if (
    !file.name.endsWith(".java") &&
    !file.name.endsWith(".class") &&
    !file.name.endsWith(".jar")
  ) {
    ElMessage.error("只能上传.java、.class或.jar文件");
    uploadFileList.value = [];
    return false;
  }
  uploadFileList.value = [file];
  return false;
};

const submitUpload = async () => {
  if (!uploadFileList.value.length) {
    ElMessage.error("请选择文件");
    return;
  }
  if (!uploadForm.shell_name) {
    ElMessage.error("请输入内存马名称");
    return;
  }

  const formData = new FormData();
  formData.append("file", uploadFileList.value[0].raw);
  formData.append("shell_name", uploadForm.shell_name);
  if (uploadForm.shell_type) {
    formData.append("shell_type", uploadForm.shell_type);
  }
  if (uploadForm.uploaded_by) {
    formData.append("uploaded_by", uploadForm.uploaded_by);
  }

  try {
    await uploadMemshell(formData);
    ElMessage.success("上传成功");
    uploadDialogVisible.value = false;
    resetUploadForm();
    fetchMemshellList();
  } catch (error: any) {
    ElMessage.error(error.message || "上传失败");
  }
};

const resetUploadForm = () => {
  uploadFileList.value = [];
  uploadForm.shell_name = "";
  uploadForm.shell_type = "";
  uploadForm.uploaded_by = "admin";
};

// 新增
const handleAdd = () => {
  addDialogVisible.value = true;
};

const submitAdd = async () => {
  if (!addForm.shell_name) {
    ElMessage.error("请输入内存马名称");
    return;
  }

  try {
    const params: any = { ...addForm };
    // 移除空值
    Object.keys(params).forEach((key) => {
      if (
        params[key] === "" ||
        params[key] === null ||
        params[key] === undefined ||
        params[key] === false
      ) {
        delete params[key];
      }
    });
    await addMemshell(params);
    ElMessage.success("新增成功");
    addDialogVisible.value = false;
    resetAddForm();
    fetchMemshellList();
  } catch (error: any) {
    ElMessage.error(error.message || "新增失败");
  }
};

const resetAddForm = () => {
  Object.keys(addForm).forEach((key) => {
    if (key === "uploaded_by") {
      addForm[key] = "admin";
    } else if (typeof addForm[key] === "boolean") {
      addForm[key] = false;
    } else {
      addForm[key] = "";
    }
  });
};

// 详情
const handleViewDetail = async (row: any) => {
  try {
    const { data } = await getMemshellDetail({ shell_id: row.id });
    detailData.value = data;
    detailDialogVisible.value = true;
  } catch (error) {
    ElMessage.error("获取详情失败");
  }
};

// 编辑
const handleEdit = (row: any) => {
  editForm.shell_id = row.id;
  editForm.shell_name = row.shell_name;
  editForm.description = row.description || "";
  editForm.risk_level = row.risk_level || "";
  editForm.tags = row.tags || "";
  editForm.is_available = row.is_available;
  editDialogVisible.value = true;
};

const handleSaveEdit = async () => {
  try {
    await updateMemshell(editForm);
    ElMessage.success("更新成功");
    editDialogVisible.value = false;
    fetchMemshellList();
  } catch (error) {
    ElMessage.error("更新失败");
  }
};

// 切换状态
const handleToggle = (row: any) => {
  const newStatus = !row.is_available;
  const action = newStatus ? "启用" : "禁用";

  ElMessageBox.confirm(`确定要${action} ${row.shell_name}?`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      try {
        await toggleMemshell({ shell_id: row.id });
        // 更新本地状态
        row.is_available = newStatus;
        ElMessage.success(`${action}成功`);
        // 刷新列表确保数据同步
        fetchMemshellList();
      } catch (error) {
        ElMessage.error("操作失败");
      }
    })
    .catch(() => {
      // 用户取消，不做任何操作，switch会保持原状态
    });
};

// 删除
const handleDelete = (row: any) => {
  ElMessageBox.confirm(`确定删除 ${row.shell_name}?`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      try {
        await deleteMemshell({ shell_id: row.id });
        ElMessage.success("删除成功");
        fetchMemshellList();
      } catch (error) {
        ElMessage.error("删除失败");
      }
    })
    .catch(() => {});
};

// 生成代码
const handleGenerate = (row: any) => {
  generateForm.shell_id = row.id;
  generateForm.password = "";
  generateForm.callback_url = "";
  generateForm.callback_port = "";
  generatedCode.value = "";
  generatedData.value = null;
  generateDialogVisible.value = true;
};

const submitGenerate = async () => {
  if (!generateForm.shell_id) {
    ElMessage.error("内存马ID不能为空");
    return;
  }
  try {
    const params: any = { ...generateForm };
    Object.keys(params).forEach((key) => {
      if (
        params[key] === "" ||
        params[key] === null ||
        params[key] === undefined
      ) {
        delete params[key];
      }
    });
    const { data } = await generateMemshell(params);
    generatedData.value = data;
    generatedCode.value = data.generated_code || "";
    ElMessage.success("生成成功");
  } catch (error: any) {
    ElMessage.error(error.message || "生成失败");
  }
};

const copyCode = () => {
  const textarea = document.createElement("textarea");
  textarea.value = generatedCode.value;
  document.body.appendChild(textarea);
  textarea.select();
  document.execCommand("copy");
  document.body.removeChild(textarea);
  ElMessage.success("已复制到剪贴板");
};

onMounted(() => {
  fetchMemshellList();
});
</script>

<template>
  <div>
    <el-card shadow="never">
      <div class="search-form-container">
        <DynamicForm
          ref="searchFormRef"
          v-model="searchForm"
          :form-config="searchConfig"
          :gutter="16"
          label-width="100px"
          type="search"
          @search="handleSearch"
          @reset="handleSearchReset"
        />
      </div>
    </el-card>

    <div style="height: 10px"></div>

    <el-card>
      <DynamicTable
        :pagination="pagination"
        :columns="columns"
        :data="memshellList"
        :loading="loading"
        @current-page-change="handlePageChange"
        @size-change="handleSizeChange"
      >
        <template #toolbar-left>
          <el-button type="primary" @click="handleUpload">
            <el-icon :size="16"><Plus /></el-icon>
            <span style="margin-left: 4px">上传内存马</span>
          </el-button>
          <el-button type="success" @click="handleAdd">
            <el-icon :size="16"><Plus /></el-icon>
            <span style="margin-left: 4px">新增内存马</span>
          </el-button>
        </template>

        <template #status="{ row }">
          <el-switch
            :model-value="row.is_available"
            @change="handleToggle(row)"
          />
        </template>

        <template #action="{ row }">
          <el-button type="primary" size="small" @click="handleViewDetail(row)"
            >详情</el-button
          >
          <el-button type="warning" size="small" @click="handleEdit(row)"
            >编辑</el-button
          >
          <el-button
            v-if="row.is_template"
            type="success"
            size="small"
            @click="handleGenerate(row)"
          >
            生成代码
          </el-button>
          <el-button type="danger" size="small" @click="handleDelete(row)"
            >删除</el-button
          >
        </template>
      </DynamicTable>
    </el-card>

    <!-- 上传对话框 -->
    <el-dialog v-model="uploadDialogVisible" title="上传内存马" width="600px">
      <el-form :model="uploadForm" label-width="120px">
        <el-form-item label="内存马名称" required>
          <el-input
            v-model="uploadForm.shell_name"
            placeholder="如: TomcatServletShell"
          />
        </el-form-item>
        <el-form-item label="类型">
          <el-select
            v-model="uploadForm.shell_type"
            placeholder="选择类型"
            style="width: 100%"
          >
            <el-option label="Servlet" value="Servlet" />
            <el-option label="Filter" value="Filter" />
            <el-option label="Listener" value="Listener" />
            <el-option label="Agent" value="Agent" />
            <el-option label="Spring" value="Spring" />
            <el-option label="JNDI" value="JNDI" />
            <el-option label="Valve" value="Valve" />
            <el-option label="WebSocket" value="WebSocket" />
          </el-select>
        </el-form-item>
        <el-form-item label="文件" required>
          <el-upload
            :auto-upload="false"
            :on-change="beforeUpload"
            :file-list="uploadFileList"
            accept=".java,.class,.jar"
            :limit="1"
          >
            <el-button type="primary">选择文件</el-button>
            <template #tip>
              <div class="el-upload__tip">支持.java、.class或.jar文件</div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="uploadDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitUpload">确定上传</el-button>
      </template>
    </el-dialog>

    <!-- 新增对话框 -->
    <el-dialog v-model="addDialogVisible" title="新增内存马" width="800px">
      <el-form :model="addForm" label-width="140px">
        <el-form-item label="内存马名称" required>
          <el-input
            v-model="addForm.shell_name"
            placeholder="如: TomcatServletShell"
          />
        </el-form-item>
        <el-form-item label="类型">
          <el-select
            v-model="addForm.shell_type"
            placeholder="选择类型"
            style="width: 100%"
          >
            <el-option label="Servlet" value="Servlet" />
            <el-option label="Filter" value="Filter" />
            <el-option label="Listener" value="Listener" />
            <el-option label="Agent" value="Agent" />
            <el-option label="Spring" value="Spring" />
            <el-option label="JNDI" value="JNDI" />
            <el-option label="Valve" value="Valve" />
            <el-option label="WebSocket" value="WebSocket" />
          </el-select>
        </el-form-item>
        <el-form-item label="描述">
          <el-input
            v-model="addForm.description"
            type="textarea"
            :rows="2"
            placeholder="内存马描述"
          />
        </el-form-item>
        <el-form-item label="Java源码">
          <el-input
            v-model="addForm.java_code"
            type="textarea"
            :rows="5"
            placeholder="粘贴Java源码"
          />
        </el-form-item>
        <el-form-item label="目标中间件">
          <el-input
            v-model="addForm.target_middleware"
            placeholder="如: Tomcat 8.5+"
          />
        </el-form-item>
        <el-form-item label="目标框架">
          <el-input
            v-model="addForm.target_framework"
            placeholder="如: Spring Boot 2.x"
          />
        </el-form-item>
        <el-form-item label="JDK版本">
          <el-input v-model="addForm.jdk_version" placeholder="如: JDK 1.8+" />
        </el-form-item>
        <el-form-item label="注入方式">
          <el-input
            v-model="addForm.injection_method"
            placeholder="如: 反射注入"
          />
        </el-form-item>
        <el-form-item label="风险等级">
          <el-select v-model="addForm.risk_level" style="width: 100%">
            <el-option label="严重" value="critical" />
            <el-option label="高危" value="high" />
            <el-option label="中危" value="medium" />
            <el-option label="低危" value="low" />
          </el-select>
        </el-form-item>
        <el-form-item label="标签">
          <el-input
            v-model="addForm.tags"
            placeholder="逗号分隔，如: Servlet,Tomcat,命令执行"
          />
        </el-form-item>
        <el-form-item label="作者">
          <el-input v-model="addForm.author" placeholder="如: security_team" />
        </el-form-item>
        <el-form-item>
          <el-checkbox v-model="addForm.has_cmd_shell"
            >支持命令执行</el-checkbox
          >
          <el-checkbox v-model="addForm.has_file_upload"
            >支持文件上传</el-checkbox
          >
          <el-checkbox v-model="addForm.is_template">是否模板</el-checkbox>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="addDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitAdd">确定</el-button>
      </template>
    </el-dialog>

    <!-- 详情对话框 -->
    <el-dialog v-model="detailDialogVisible" title="内存马详情" width="1000px">
      <el-descriptions v-if="detailData" :column="2" border>
        <el-descriptions-item label="ID">{{
          detailData.id
        }}</el-descriptions-item>
        <el-descriptions-item label="名称">{{
          detailData.shell_name
        }}</el-descriptions-item>
        <el-descriptions-item label="类型">{{
          detailData.shell_type
        }}</el-descriptions-item>
        <el-descriptions-item label="描述" :span="2">{{
          detailData.description
        }}</el-descriptions-item>
        <el-descriptions-item label="目标中间件">{{
          detailData.target_middleware
        }}</el-descriptions-item>
        <el-descriptions-item label="目标框架">{{
          detailData.target_framework || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="JDK版本">{{
          detailData.jdk_version
        }}</el-descriptions-item>
        <el-descriptions-item label="操作系统">{{
          detailData.os_support
        }}</el-descriptions-item>
        <el-descriptions-item label="文件大小"
          >{{ detailData.file_size }} 字节</el-descriptions-item
        >
        <el-descriptions-item label="文件哈希">{{
          detailData.file_hash
        }}</el-descriptions-item>
        <el-descriptions-item label="风险等级">
          <el-tag
            :type="detailData.risk_level === 'critical' ? 'danger' : 'warning'"
          >
            {{ detailData.risk_level }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="是否模板">
          <el-tag :type="detailData.is_template ? 'warning' : 'info'">
            {{ detailData.is_template ? "是" : "否" }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="状态">
          <el-tag :type="detailData.is_available ? 'success' : 'danger'">
            {{ detailData.is_available ? "启用" : "禁用" }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="标签" :span="2">{{
          detailData.tags || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="作者">{{
          detailData.author || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="上传者">{{
          detailData.uploaded_by
        }}</el-descriptions-item>
        <el-descriptions-item label="上传时间">{{
          detailData.uploaded_at
        }}</el-descriptions-item>
        <el-descriptions-item label="更新时间">{{
          detailData.updated_at
        }}</el-descriptions-item>
      </el-descriptions>
    </el-dialog>

    <!-- 编辑对话框 -->
    <el-dialog v-model="editDialogVisible" title="编辑内存马" width="600px">
      <el-form :model="editForm" label-width="100px">
        <el-form-item label="名称">
          <el-input v-model="editForm.shell_name" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="editForm.description" type="textarea" :rows="3" />
        </el-form-item>
        <el-form-item label="风险等级">
          <el-select v-model="editForm.risk_level" style="width: 100%">
            <el-option label="严重" value="critical" />
            <el-option label="高危" value="high" />
            <el-option label="中危" value="medium" />
            <el-option label="低危" value="low" />
          </el-select>
        </el-form-item>
        <el-form-item label="标签">
          <el-input
            v-model="editForm.tags"
            placeholder="逗号分隔，如: Servlet,Tomcat,命令执行"
          />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="editForm.is_available" style="width: 100%">
            <el-option :label="'启用'" :value="true">启用</el-option>
            <el-option :label="'禁用'" :value="false">禁用</el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="editDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSaveEdit">确定</el-button>
      </template>
    </el-dialog>

    <!-- 生成代码对话框 -->
    <el-dialog
      v-model="generateDialogVisible"
      title="生成定制化内存马"
      width="900px"
    >
      <el-form :model="generateForm" label-width="100px">
        <el-form-item label="内存马ID">
          <span>{{ generateForm.shell_id }}</span>
        </el-form-item>
        <el-form-item label="访问密码">
          <el-input
            v-model="generateForm.password"
            placeholder="可选，自定义密码"
          />
        </el-form-item>
        <el-form-item label="回连地址">
          <el-input
            v-model="generateForm.callback_url"
            placeholder="可选，如: http://1.2.3.4"
          />
        </el-form-item>
        <el-form-item label="回连端口">
          <el-input
            v-model="generateForm.callback_port"
            placeholder="可选，如: 4444"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitGenerate">生成</el-button>
        </el-form-item>
        <el-form-item v-if="generatedData" label="生成信息">
          <el-alert
            :title="generatedData.shell_name"
            :description="`类型: ${generatedData.shell_type}`"
            type="info"
            style="margin-bottom: 10px"
          />
        </el-form-item>
        <el-form-item v-if="generatedCode" label="生成代码">
          <div style="display: flex; gap: 10px; margin-bottom: 10px">
            <el-button size="small" @click="copyCode">复制代码</el-button>
          </div>
          <el-input
            type="textarea"
            :model-value="generatedCode"
            readonly
            :rows="20"
            style="font-family: monospace; font-size: 12px"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="generateDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.search-form-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
</style>
